package cn.tpshion.pulsar.support;

import lombok.AllArgsConstructor;
import lombok.Data;
import org.apache.pulsar.client.api.Schema;
import org.apache.pulsar.client.api.SubscriptionType;
import org.springframework.boot.context.properties.ConfigurationProperties;

import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * pulsar属性配置类
 */
@Data
@ConfigurationProperties(prefix = "spring.pulsar")
public class PulsarProperties {

    public static final String PERSISTENT = "persistent";

    /**
     * 服务端连接地址
     * 默认本地
     */
    private String serviceUrl = "pulsar://localhost:6650";

    private String token;

    /**
     * Set the operation timeout (default: 30 seconds).
     * Producer-create, subscribe and unsubscribe operations will be retried until this
     * interval, after which the operation will be marked as failed
     */
    private TimeConfig operationTimeout = new TimeConfig(30, TimeUnit.SECONDS);

    /**
     * Set the number of threads to be used for handling connections to brokers
     * (default: 1 thread).
     */
    private int ioThreads = 1;

    /**
     * Set the number of threads to be used for message listeners (default: 1 thread).
     * The listener thread pool is shared across all the consumers and readers that are
     * using a "listener" model to get messages. For a given consumer, the listener will
     * be always invoked from the same thread, to ensure ordering.
     */
    private int listenerThreads = 1;

    /**
     * Release the connection if it is not used for more than connectionMaxIdleSeconds
     * seconds.If connectionMaxIdleSeconds < 0, disabled the feature that auto release
     * the idle connection
     */
    private int connectionMaxIdleSeconds = 180;

    private boolean enableTcpNoDelay = true;

    private TimeConfig keepAliveInterval = new TimeConfig(30, TimeUnit.SECONDS);

    private TimeConfig connectionTimeout = new TimeConfig(10, TimeUnit.SECONDS);

    private List<PulsarProducer> producers;

    private List<PulsarConsumer> consumers;

    private SubscriptionType subscriptionType = SubscriptionType.Exclusive;

    private TopicSchema topicSchema = TopicSchema.STRING;

    private Schema schema = Schema.STRING;

    enum TopicSchema {
        BYTES("BYTES", Schema.BYTES),
        BYTEBUFFER("BYTEBUFFER", Schema.BYTEBUFFER),
        STRING("STRING", Schema.STRING),
        INT8("INT8", Schema.INT8),
        INT16("INT16", Schema.INT16),
        BOOL("BOOL", Schema.BOOL),
        FLOAT("FLOAT", Schema.FLOAT),
        DOUBLE("DOUBLE", Schema.DOUBLE),
        DATE("DATE", Schema.DATE),
        TIME("TIME", Schema.TIME);

        private String type;
        private Schema schema;

        TopicSchema(String type, Schema schema){
            this.type = type;
            this.schema = schema;
        }

        public String getType() {
            return type;
        }

        public void setType(String type) {
            this.type = type;
        }

        public Schema getSchema() {
            return schema;
        }

        public void setSchema(Schema schema) {
            this.schema = schema;
        }
    }

    public void setTopicSchema(TopicSchema topicSchema) {
        this.topicSchema = topicSchema;
        this.schema = topicSchema.getSchema();
    }

    @Data
    @AllArgsConstructor
    public static class TimeConfig{
        private int timeOut;
        private TimeUnit timeUnit;
    }

}
